﻿#ifndef SAFRAMELESSHELPER_H
#define SAFRAMELESSHELPER_H

#include "SARibbonGlobal.h"
#include <QObject>
#include <QHash>
#include <QPoint>

class QWidget;
class QRubberBand;
class QMouseEvent;
class QHoverEvent;
class FramelessHelperPrivate;

/*****
* CursorPosCalculator
* 计算鼠标是否位于左、上、右、下、左上角、左下角、右上角、右下角
*****/
class CursorPosCalculator
{
public:
    explicit CursorPosCalculator();
    void reset();
    void recalculate(const QPoint& globalMousePos, const QRect& frameRect);

public:
    bool m_bOnEdges : true;
    bool m_bOnLeftEdge : true;
    bool m_bOnRightEdge : true;
    bool m_bOnTopEdge : true;
    bool m_bOnBottomEdge : true;
    bool m_bOnTopLeftEdge : true;
    bool m_bOnBottomLeftEdge : true;
    bool m_bOnTopRightEdge : true;
    bool m_bOnBottomRightEdge : true;

    static int m_nBorderWidth;
    static int m_nTitleHeight;
};
/*****
* WidgetData
* 更新鼠标样式、移动窗体、缩放窗体
*****/
class SA_RIBBON_EXPORT WidgetData : public QObject
{
    Q_OBJECT
public:
    explicit WidgetData(FramelessHelperPrivate* d, QWidget* pTopLevelWidget);
    ~WidgetData();
    QWidget* widget();

    // 处理鼠标事件-划过、按下、释放、移动
    bool handleWidgetEvent(QEvent* event);

    // 更新橡皮筋状态
    void updateRubberBandStatus();

//signals:
//    void signal_updateWidgetCursor(Qt::CursorShape shap);
//    void signal_resetWidgetCursor();

private:
    // 更新鼠标样式
    void updateCursorShape(const QPoint& gMousePos);

    // 重置窗体大小
    void resizeWidget(const QPoint& gMousePos);

    // 移动窗体
    void moveWidget(const QPoint& gMousePos);

    // 处理鼠标按下
    bool handleMousePressEvent(QMouseEvent* event);

    // 处理鼠标释放
    bool handleMouseReleaseEvent(QMouseEvent* event);

    // 处理鼠标移动
    bool handleMouseMoveEvent(QMouseEvent* event);

    // 处理鼠标离开
    bool handleLeaveEvent(QEvent* event);

    // 处理鼠标进入
    bool handleHoverMoveEvent(QHoverEvent* event);

    //处理鼠标双击事件
    bool handleDoubleClickedMouseEvent(QMouseEvent* event);

private:
    FramelessHelperPrivate* d;
    QRubberBand* m_pRubberBand;
    QWidget* m_pWidget;
    QPoint m_ptDragPos;
    CursorPosCalculator m_pressedMousePos;
    CursorPosCalculator m_moveMousePos;
    bool m_bLeftButtonPressed;
    bool m_bCursorShapeChanged;
    bool m_bLeftButtonTitlePressed;
    Qt::WindowFlags m_windowFlags;
};

/*****
* FramelessHelperPrivate
* 存储界面对应的数据集合，以及是否可移动、可缩放属性
*****/
class FramelessHelperPrivate
{
public:
    QHash<QWidget*, WidgetData*> m_widgetDataHash;
    bool m_bWidgetMovable : true;
    bool m_bWidgetResizable : true;
    bool m_bRubberBandOnResize : true;
    bool m_bRubberBandOnMove : true;
};


class SA_RIBBON_EXPORT SAFramelessHelper : public QObject
{
    Q_OBJECT

public:
    explicit SAFramelessHelper(QObject *parent);
    ~SAFramelessHelper();
    // 激活窗体
    void activateOn(QWidget *topLevelWidget);

    // 移除窗体
    void removeFrom(QWidget *topLevelWidget);

    // 设置窗体移动
    void setWidgetMovable(bool movable);

    // 设置窗体缩放
    void setWidgetResizable(bool resizable);

    // 设置橡皮筋移动
    void setRubberBandOnMove(bool movable);

    // 设置橡皮筋缩放
    void setRubberBandOnResize(bool resizable);

    // 设置边框的宽度
    void setBorderWidth(int width);

    // 设置标题栏高度
    void setTitleHeight(int height);
    bool widgetResizable();
    bool widgetMovable();
    bool rubberBandOnMove();
    bool rubberBandOnResisze();
    uint borderWidth();
    uint titleHeight();

    // 事件过滤，进行移动、缩放等
    virtual bool eventFilter(QObject *obj, QEvent *event);

    WidgetData* getWidgetData(QWidget* widget);
private:
    FramelessHelperPrivate *d;
};

#endif // FRAMELESSHELPER_H
